<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="/js/eventMap.js"></script>
<script type="text/javascript" src="/js/atnd.js"></script>
<script type="text/javascript" src="/js/timer.js"></script>
<script type="text/javascript" src="/js/notification.js"></script>
<script type="text/javascript" src="/js/options.js"></script>
<script type="text/javascript" src="/js/manifest.js"></script>
<script type="text/javascript">
var options = Options.load();
var notification = new Notification('html/notification.html', 1000 * options.autoCloseTimeSS);
var timer = new Timer(1000 * 60 * options.timerMI); // n分に一回

function main(options) {
	extensionUpdateNotify(options);

	timer.start(function () {
		console.log("timer run");
		console.log(options);
		updateUserEventList(options);
		eventUserStatusNotify(options);
		eventStartDateNotifyAndEventUpdateNotify(options);
		keywordNotify(options);
		ownerNotify(options);
		userOwnerEventCapacityNotify(options);
	});
}
main(options);

// ATND Notifyがバージョンアップされたら通知
function extensionUpdateNotify(options) {
	var manifest = Manifest.load();
	if (options.appVersion == "0.0.0.0") {
		// 初期インストール
		options.appVersion = manifest.version;
		options.save();
	} else if (options.appVersion != manifest.version) {
		// アップデート
		if (options.appVersion.substring(0, options.appVersion.lastIndexOf(".")) != manifest.version.substring(0, manifest.version.lastIndexOf("."))) {
			// 末尾のバージョンNoを除いた値が更新されていたら通知(末尾のバージョンNoだけが変わっている場合は通知しない)
			notification.open({version:manifest.version});
		}
		options.appVersion = manifest.version;
		options.save();
	}
}

// 参加イベントの一覧を更新する
function updateUserEventList(options) {
	if (options.user_id == '') {
		return;
	}
	var events = Atnd.findByUserId(options.user_id);
	var userEventCount = options.user_events.length;
	var map = new EventMap(options.user_events);
	events.forEach(function (event) {
		var userEvent = map.get(event.event_id);
		if (userEvent == null) {
			var status = 0;
			event.users.forEach(function (user) {
				if (options.user_id == user.user_id) {
					status = user.status;
				}
			});
			map.put({event_id:event.event_id, title:event.title, status:status, updated_at:event.updated_at, dateNotifiedList:[]});
		}
	});
	options.user_events = map.toArray();

	if (userEventCount == 0 && userEventCount < options.user_events.length) {
		// 初回だけ
		notification.open({title:"イベントカレンダーを更新", msg: "クリックしてカレンダーを確認してください。"});
	}

	options.user_events.forEach(function (userEvent) {
		if (userEvent.started_at != null) {
			return;
		}
		var atnd = new Atnd(userEvent.event_id);
		var event = atnd.getEvent();
		if (event == null) {
			return;
		}
		userEvent.started_at = event.started_at;
		userEvent.ended_at = event.ended_at;
		userEvent.owner_id = event.owner_id;
		userEvent.owner_nickname = event.owner_nickname;
		userEvent.accepted = event.accepted;
		userEvent.limit = event.limit;
		userEvent.waiting = event.waiting;
		userEvent.address = event.address;
		userEvent.lon = event.lon;
		userEvent.lat = event.lat;
		addEventCalendarList(options, event);
	});
	options.save();
}

// イベントの開催日時が近づいたら通知、イベントに変更があったら通知
function eventStartDateNotifyAndEventUpdateNotify(options) {

	// 終了していないイベントを抽出
	var eventList = Atnd.filterIsNotEndedEventList(options.user_events);
	var now = new Date();
	eventList.forEach(function (userEvent) {
		console.debug(userEvent);
		var atnd = new Atnd(userEvent.event_id);
		var event = atnd.getEvent();
		if (event == null) {
			return;
		}
		addEventCalendarList(options, event);
		userEvent.started_at = event.started_at;
		userEvent.ended_at = event.ended_at;
		userEvent.accepted = event.accepted;
		userEvent.limit = event.limit;
		userEvent.waiting = event.waiting;
		userEvent.address = event.address;
		userEvent.lon = event.lon;
		userEvent.lat = event.lat;


		// 何日前に備忘通知
		var eventDate = Atnd.toDate(event.started_at);
		var isNotified = false;
		options.dateNotifyList.forEach(function (dateNotify) {
			if ($.inArray(dateNotify, userEvent.dateNotifiedList) > -1) {
				return; // 過去に通知済み
			}
			var sai = (now - eventDate) * -1; // 差分ミリ秒数
			var time = (1000 * 60 * 60 * 24) * dateNotify;
			if (time >= sai) {
				if (!isNotified) {
					notification.open({event_id:event.event_id, title:event.title, msg:"(備忘通知)開催日時" + toDateString(eventDate) + '～'});
					isNotified = true;
				}
				userEvent.dateNotifiedList.push(dateNotify);
			}
		});

		if (event.updated_at > userEvent.updated_at) {
			userEvent.updated_at = event.updated_at;
			notification.open({event_id:event.event_id, title:event.title, msg:"イベント内容に変更がありました"});
		}
	});

	options.save();
}

function toDateString(date) {
	var yyyy = date.getFullYear();
	var mm = date.getMonth() + 1;
	var dd = date.getDate();
	var hh = date.getHours();
	var mi = date.getMinutes();
	if (mm < 10) mm = "0" + mm;
	if (dd < 10) dd = "0" + dd;
	if (hh < 10) hh = "0" + hh;
	if (mi < 10) mi = "0" + mi;
	var days = ['日', '月', '火', '水', '木', '金', '土'];
	return yyyy + '/' + mm + '/' + dd + '(' + days[date.getDay()] + ') ' + hh + ':' + mi;
}

// キャンセル待ち→出席になったら通知
function eventUserStatusNotify(options) {
	// 終了していないイベントを抽出
	var eventList = Atnd.filterIsNotEndedEventList(options.user_events);
	eventList.forEach(function (userEvent) {
		console.debug(userEvent);
		if (userEvent.status == 1) {
			return; // 既に出席
		}
		var atnd = new Atnd(userEvent.event_id);
		var status = atnd.getStatus(options.user_id);
		if (status == 1) {
			userEvent.status = 1; // キャンセル待ち→出席
			notification.open({event_id:userEvent.event_id, title:userEvent.title, msg:"参加できるようになりました"});
		}
	});
	options.save();
}

// 特定キーワードを含むイベントが見つかったら通知する
function keywordNotify(options) {
	var list = {};
	options.keywordList.forEach(function (keyword){
		console.debug("keyword:" + keyword);
		var events = Atnd.findByKeyword(keyword);
		events.forEach(function (event){
			addEventCalendarList(options, event);
			if ($.inArray(event.event_id, options.keywordNotifiedList) == -1) {
				if (list[keyword] == null) {
					list[keyword] = 1;
				} else {
					list[keyword]++;
				}
				options.keywordNotifiedList.push(event.event_id);
			}
		});
	});
	Object.keys(list).forEach(function(keyword){
		var count = list[keyword];
		notification.open({title:keyword, msg: count + "件のイベントが見つかりました。クリックしてカレンダーを確認してください。"});
	});
	options.save();
}

// 特定の管理人がイベントを立てたら通知する
function ownerNotify(options) {
	options.ownerList.forEach(function (owner){
		console.debug(owner);
		var events = Atnd.findByOwnerId(owner.user_id);
		events.forEach(function (event){
			addEventCalendarList(options, event);
			if (Atnd.toDate(owner.updated_at) < Atnd.toDate(event.updated_at)) {
				owner.updated_at = event.updated_at;
				if ($.inArray(event.event_id, options.ownerNotifiedList) == -1) {
					notification.open({event_id:event.event_id, title:event.title, msg:owner.nickname + "さんが新規イベントを作成しました。"});
					options.ownerNotifiedList.push(event.event_id);
				}
			}
		});
	});
	options.save();
}

// 自分が立てたイベントが満席になったら通知
function userOwnerEventCapacityNotify(options) {
	if (options.user_id == '') {
		return;
	}
	var events = Atnd.findByOwnerId(options.user_id);
	events.forEach(function (event) {
		if (event.limit && event.limit <= event.accepted) {
			if ($.inArray(event.event_id, options.userCapacityNotifiedList) == -1) {
				notification.open({event_id:event.event_id, title:event.title, msg:"満席になりました。\n定員:"+  event.limit + ' キャンセル待ち:' + event.waiting});
				options.userCapacityNotifiedList.push(event.event_id);
			}
		}
	});
	options.save();
}

// イベントカレンダーに登録する
function addEventCalendarList(options, event) {
	var map = new EventMap(options.eventCalendarList);
	if (map.get(event.event_id) == null || map.get(event.event_id).updated_at < event.updated_at) {
		event.attention = true;
		map.put(event);
	}
	options.eventCalendarList = map.toArray();
}

//緯度経度から住所を取得する
function latlngToAddress(lat, lon, callback) {
	var latlng = lat + ',' + lon;
	$.ajax({
	  url : 'http://maps.google.com/maps/api/geocode/json',
	  data : {
	    latlng: latlng,
	    sensor: true
	  },
	  dataType : 'json',
	  success : function(json){
		var result = "";
		var address = json.results[0];
		if (address && address.formatted_address) {
			result = address.formatted_address.replace('日本, ', '');
		}
		callback(result);
	  }
	});
}

// notification.html, content_scripts.jsとのメッセージ送受信イベント割り当て
chrome.extension.onRequest.addListener(function(message, sender, sendResponse){
	console.debug(message);
	if (message.id === 'content_script_options') {
		sendResponse(options);
	} else if (message.id === 'content_script_userId') {
		var isUpdate = (options.user_id != message.userId);
		options.user_id = message.userId;
		options.user_nickname = message.nickname;
		options.save();
		if (isUpdate) {
			timer.restart();
		}
		sendResponse();
	} else if (message.id === 'content_script_ownerId') {
		if (!message.isDelete) {
			// 通知設定
			var now = new Date();
			options.ownerList.push({user_id:message.ownerId, nickname:message.ownerNickname, updated_at:now.toISOString().substring(0,10) + "T" + now.toLocaleTimeString()});
			notification.open({ownerId:message.ownerId, title:'イベント通知設定', name:message.ownerNickname, msg:message.ownerNickname + "さんを通知設定しました"});
		} else {
			// 通知解除
			var list = [];
			$.each(options.ownerList, function (i, owner){
				if (message.ownerId != owner.user_id) {
					list.push(owner);
				}
			});
			options.ownerList = list;
			notification.open({ownerId:message.ownerId, title:'イベント通知設定', name:message.ownerNickname, msg:message.ownerNickname + "さんの通知設定を解除しました"});
		}
		options.save();
		sendResponse();
	} else if (message.id === 'getLatlngToAddress') {
		latlngToAddress(message.lat, message.lon, function (fromAddress) {
			sendResponse(fromAddress);
		});
	} else if (message.id == 'window.open') {
		window.open(message.url, message.target);
		sendResponse();
    } else {
		// notification.html
		sendResponse(notification.getItem(message.id));
	}
});
</script>
</head>
<body>
</body>
</html>